package com.fc.v2.controller;


import com.alibaba.fastjson.JSONObject;
import com.fc.v2.common.base.BaseController;
import com.fc.v2.common.domain.Product;
import com.fc.v2.common.domain.ResuTree;
import com.fc.v2.model.*;
import com.fc.v2.util.MD5Util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.*;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@RestController
@CrossOrigin
public class productsController extends BaseController {


    @Autowired
    private RestTemplate restTemplate;

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }

    private static String appId = "E42E540CA35B9AEEFAB1960A64A07AF8";
    private static String appKey = "987407407774565305";


    /**
     * 库存数量top10
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    @GetMapping("/getProductStock")
    public ResuTree getProductStock() throws IOException, NoSuchAlgorithmException {
        //获取所有商品
        List<ProductModel> productModelList = new ArrayList<>();
        getAllProduct(null, productModelList);
        if (CollectionUtils.isEmpty(productModelList)){
            return dataTree("无商品数据");
        }
        return dataTree(productModelList.stream().sorted(Comparator.comparing(ProductModel::getStock).reversed()).limit(10));
    }

    /**
     * 缺货商品数量
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    @GetMapping("/getProductSale")
    public ResuTree getProductSale() throws IOException, NoSuchAlgorithmException {
        //获取所有商品
        List<OrderModel> orderModelList = new ArrayList<>();
        getAllOrder(null, orderModelList);
        if (CollectionUtils.isEmpty(orderModelList)){
            return dataTree("无订单数据");
        }
        //处理订单中 item数据 按照商品id分组 叠加销售个数 再进行排序
        List<OrderModel.Item> itemList = new ArrayList<>();
        return dataTree(buildItemList(orderModelList, itemList).stream().sorted(Comparator.comparing(ItemModel::getQuantity).reversed()).limit(10));
    }


    /**
     * 缺货率
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    @GetMapping("/getProductRate")
    public ResuTree getProductRate() throws IOException, NoSuchAlgorithmException {
        //获取所有商品
        List<ProductModel> productModelList = new ArrayList<>();
        getAllProduct(null, productModelList);
        if (CollectionUtils.isEmpty(productModelList)){
            return dataTree("无商品数据");
        }
        BigDecimal productStock = new BigDecimal(productModelList.stream().filter(p -> p.getStock().equals(BigDecimal.ZERO)).collect(Collectors.toList()).size());
        BigDecimal bigDecimal = new BigDecimal(productModelList.size());
        BigDecimal productRate = productStock.divide(bigDecimal, 2, BigDecimal.ROUND_HALF_UP);
        return dataTree(productRate);
    }






    public List<ItemModel> buildItemList( List<OrderModel> orderModelList,List<OrderModel.Item> itemList){
        //处理订单中 item数据 按照商品id分组 叠加销售个数 再进行排序
        orderModelList.forEach(o -> itemList.addAll(o.getItems()));
        Map<Long, List<OrderModel.Item>> itemMap = itemList.stream().collect(Collectors.groupingBy(OrderModel.Item::getProductUid));
        Iterator<Map.Entry<Long, List<OrderModel.Item>>> iterator = itemMap.entrySet().iterator();
        List<ItemModel> items = new ArrayList<>();
        while (iterator.hasNext()){
            List<OrderModel.Item> value = iterator.next().getValue();
            BigDecimal quantity = new BigDecimal("0");
            for (OrderModel.Item i : value) {
                quantity = quantity.add(i.getQuantity());
            }
            ItemModel item = new ItemModel();
            item.setQuantity(quantity);
            item.setItemName(value.get(0).getName());
            items.add(item);
        }
        return items;
    }


    public List<OrderModel> getAllOrder(PostBackParameter postBackParameter, List<OrderModel> orderModelList) throws IOException, NoSuchAlgorithmException {
        String getTenUrl = "https://area76-win.pospal.cn:443/pospal-api2/openapi/v1/ticketOpenApi/queryTicketPages";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("appId", appId);
        jsonObject.put("startTime", getStartOfDay(new Date()));
        jsonObject.put("endTime", getEndOfDay(new Date()));
        if (Objects.nonNull(postBackParameter)) {
            JSONObject jsonPostBackParameter = new JSONObject();
            jsonPostBackParameter.put("parameterType", postBackParameter.getParameterType());
            jsonPostBackParameter.put("parameterValue", postBackParameter.getParameterValue());
            jsonObject.put("postBackParameter", jsonPostBackParameter);
        }
        //获取签名
        String dataSignature = MD5Util.encryptToMd5String(JSONObject.toJSONString(jsonObject), appKey);
        String requestData = sendRequestData(getTenUrl, dataSignature, JSONObject.toJSONString(jsonObject));
        JSONObject resObj = JSONObject.parseObject(requestData);
        Object data = resObj.get("data");
        OrderResult orderResult = JSONObject.parseObject(JSONObject.toJSONString(data), OrderResult.class);
        List<OrderModel> result = orderResult.getResult();
        orderModelList.addAll(result);
        if (CollectionUtils.isEmpty(result) || result.size() < 100) {
            return orderModelList;
        }
        getAllOrder(orderResult.getPostBackParameter(), orderModelList);
        return orderModelList;
    }




    public List<ProductModel> getAllProduct(PostBackParameter postBackParameter, List<ProductModel> productModelList) throws IOException, NoSuchAlgorithmException {
        String getTenUrl = "https://area76-win.pospal.cn:443/pospal-api2/openapi/v1/productOpenApi/queryProductPages";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("appId", appId);
        jsonObject.put("startTime", getStartOfDay(new Date()));
        jsonObject.put("endTime", getEndOfDay(new Date()));
        if (Objects.nonNull(postBackParameter)) {
            JSONObject jsonPostBackParameter = new JSONObject();
            jsonPostBackParameter.put("parameterType", postBackParameter.getParameterType());
            jsonPostBackParameter.put("parameterValue", postBackParameter.getParameterValue());
            jsonObject.put("postBackParameter", jsonPostBackParameter);
        }
        //获取签名
        String dataSignature = MD5Util.encryptToMd5String(JSONObject.toJSONString(jsonObject), appKey);
        String requestData = sendRequestData(getTenUrl, dataSignature, JSONObject.toJSONString(jsonObject));
        JSONObject resObj = JSONObject.parseObject(requestData);
        Object data = resObj.get("data");
        ProductResult productResult = JSONObject.parseObject(JSONObject.toJSONString(data), ProductResult.class);
        List<ProductModel> result = productResult.getResult();
        productModelList.addAll(result);
        if (CollectionUtils.isEmpty(result) || result.size() < 100) {
            return productModelList;
        }
        getAllProduct(productResult.getPostBackParameter(), productModelList);
        return productModelList;
    }


    public String sendRequestData(String urlString, String dataSignature, String arg) throws IOException {
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
        requestHeaders.set("time-stamp", System.currentTimeMillis() + "");
        requestHeaders.set("data-signature", dataSignature);
        List charset = new ArrayList<Charset>();
        charset.add(Charset.forName("UTF-8"));
        requestHeaders.setAcceptCharset(charset);
        ResponseEntity<String> responseEntity = restTemplate.exchange(urlString, HttpMethod.POST, new HttpEntity<>(arg, requestHeaders), String.class);
        return responseEntity.getBody();
    }

    public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        Product product = new Product();
        product.setAppId("DD95CC8FAB544F6B03C1888CFB05A07F");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("appId", "E42E540CA35B9AEEFAB1960A64A07AF8");
        jsonObject.put("startTime", "2023-06-28 00:00:00");
        jsonObject.put("endTime", "2023-06-28 23:59:59");

        JSONObject jsonObject2 = new JSONObject();
        jsonObject2.put("parameterType", "LAST_RESULT_MAX_ID");
        jsonObject2.put("parameterValue", "9893772");

        jsonObject.put("postBackParameter", jsonObject2);
        System.out.println(JSONObject.toJSON(jsonObject));
        System.out.println(MD5Util.encryptToMd5String(JSONObject.toJSONString(jsonObject), "987407407774565305"));

        BaseRequest baseRequest = new BaseRequest();
        baseRequest.setAppId("E42E540CA35B9AEEFAB1960A64A07AF8");
        baseRequest.setStartTime("2023-06-28 00:00:00");
        baseRequest.setEndTime("2023-06-28 23:59:59");
        System.out.println(JSONObject.toJSONString(baseRequest));
        System.out.println(MD5Util.encryptToMd5String(JSONObject.toJSONString(baseRequest), "987407407774565305"));


        String STR = "{\n" +
                "    \"appId\": \"E42E540CA35B9AEEFAB1960A64A07AF8\",\n" +
                "    \"startTime\": \"2023-06-28 00:00:00\",\n" +
                "    \"endTime\": \"2023-06-28 23:59:59\"\n" +
                "}";
        System.out.println(STR);
        String dataSignature = MD5Util.encryptToMd5String(STR, "987407407774565305");
        System.out.println(dataSignature);
        System.out.println(System.currentTimeMillis());

    }

    // 获得某天最大时间
    public static String getStartOfDay(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
    }


    // 获得某天最小时间
    public static String getEndOfDay(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
    }


}
